const db = require('../../MySql');
const { formatDateTime } = require('../utils/dateUtils')
const { generate19DigitId } = require('../utils/idUtils')

/**
 * 试卷模型类
 * 对应数据库中的 el_paper 表
 * 用于封装用户考试答卷相关的数据和业务逻辑
 */
class el_paper {
    /**
     * 构造函数 - 创建试卷对象实例
     * @param {string} id - 试卷ID，唯一标识符
     * @param {string} user_id - 用户ID，答卷所属的用户
     * @param {string} depart_id - 部门ID，用户所属的部门
     * @param {string} exam_id - 考试ID，关联的考试
     * @param {string} title - 试卷标题，通常与考试标题一致
     * @param {number} total_time - 总时长（分钟），考试规定的总时间
     * @param {number} user_time - 用户用时（分钟），用户实际花费的时间
     * @param {number} total_score - 总分，试卷的总分数
     * @param {number} qualify_score - 及格分数，通过考试所需的最低分数
     * @param {number} obj_score - 客观题得分，选择题、判断题等客观题的得分
     * @param {number} subj_score - 主观题得分，简答题、论述题等主观题的得分
     * @param {number} user_score - 用户得分，用户最终获得的分数
     * @param {boolean} has_saq - 是否有主观题，true表示包含主观题需要人工阅卷
     * @param {number} state - 试卷状态（0 正在考试 ,1 没有正在考试，2 已考完）
     * @param {string} create_time - 创建时间，答卷创建的时间戳
     * @param {string} update_time - 更新时间，答卷最后修改的时间戳
     * @param {number} limit_time - 截止时间（分钟），考试允许的最晚提交时间
     * 
     * 使用示例：
     * const paper = new el_paper(
     *     'paper123', 'user456', 'depart789', 'exam001',
     *     'JavaScript基础考试答卷',
     *     120, 95, 100, 60,
     *     40, 35, 75, true,
     *     2, '2024-01-01 09:00:00', '2024-01-01 10:35:00', '2024-01-01 10:35:00'
     * );
     */
    constructor(id, user_id, depart_id, exam_id, title, total_time, user_time, total_score, qualify_score, obj_score, subj_score, user_score, has_saq, state, create_time, update_time, limit_time) {
        this.id = id;
        this.title = title;
        this.exam_id = exam_id;
        this.user_id = user_id;
        this.depart_id = depart_id;
        this.total_time = total_time;
        this.user_time = user_time;
        this.total_score = total_score;
        this.qualify_score = qualify_score;
        this.obj_score = obj_score;
        this.subj_score = subj_score;
        this.user_score = user_score;
        this.has_saq = has_saq;
        this.state = state;
        this.create_time = create_time;
        this.update_time = update_time;
        this.limit_time = limit_time;
    }

     /**
      * 根据试卷ID查询考试试卷
      * @param {string} exam_id - 考试ID，唯一标识符
      * @returns {Promise<el_paper[]>} - 返回包含所有符合条件的el_paper对象实例的数组
      */
     static async findByExamId(exam_id) {
        // 执行SQL查询，获取所有用户数据
        const [results] = await db.query('select * from el_paper where exam_id = ? ', [exam_id])

        // 将查询结果映射为sys_user对象实例
        return results.map(item => new el_paper(
            item.id,
            item.user_id,
            item.depart_id,
            item.exam_id,
            item.title,
            item.total_time,
            item.user_time,
            item.total_score,
            item.qualify_score,
            item.obj_score,
            item.subj_score,
            item.user_score,
            item.has_saq,
            item.state,
            formatDateTime(item.create_time),
            formatDateTime(item.update_time),
            formatDateTime(item.limit_time),
        ))
    }

    /**
      * 根据试卷状态查询考试试卷（支持分页和排序）
      * @param {number} limit - 查询记录数量限制
      * @param {number} offset - 查询偏移量
      * @returns {Promise<el_paper[]>}
    */
    static async elPaperPaging(limit = 10, offset = 0, userId) {
        let sql = `select * from el_paper where user_id=? order by create_time DESC`;
        const params = [userId]

        if (limit > 0) {
            sql += ' limit ? offset ?';
            params.push(limit, offset);
        }

        const [results] = await db.query(sql, params)
        return results.map(item => new el_paper(
            item.id,
            item.user_id,
            item.depart_id,
            item.exam_id,
            item.title,
            item.total_time,
            item.user_time,
            item.total_score,
            item.qualify_score,
            item.obj_score,
            item.subj_score,
            item.user_score,
            item.has_saq,
            item.state,
            formatDateTime(item.create_time),
            formatDateTime(item.update_time),
            formatDateTime(item.limit_time),
        ))
    }

    /**
     * 根据试卷状态查询考试试卷
     * 用于获取所有状态为指定值的考试试卷记录，通常用于查看已完成或未完成的考试
     * @param {number} state - 试卷状态，0 正在考试 ,1 没有正在考试，2 已考完
     * @returns {Promise<el_paper[]>} - 返回包含所有符合条件的el_paper对象实例的数组
     */
    static async findByPaperState(state) {
        // 执行SQL查询，获取所有用户数据
        const [results] = await db.query('select * from el_paper where state = ? ', [state])

        // 将查询结果映射为sys_user对象实例
        return results.map(item => new el_paper(
            item.id,
            item.user_id,
            item.depart_id,
            item.exam_id,
            item.title,
            item.total_time,
            item.user_time,
            item.total_score,
            item.qualify_score,
            item.obj_score,
            item.subj_score,
            item.user_score,
            item.has_saq,
            item.state,
            formatDateTime(item.create_time),
            formatDateTime(item.update_time),
            formatDateTime(item.limit_time),
        ))
    }

    /**
     * 根据试卷状态和用户ID查询考试试卷
     * 用于获取特定用户在指定状态下的所有考试试卷记录，通常用于查看用户已完成或未完成的考试
     * @param {number} state - 试卷状态，0 正在考试 ,1 没有正在考试，2 已考完
     * @param {string} userId - 用户ID，用于筛选特定用户的考试记录
     * @returns {Promise<el_paper[]>} - 返回包含所有符合条件的el_paper对象实例的数组
     */
    static async findByPaperStateAndUserId(state, userId) {
        // 执行SQL查询，获取所有用户数据
        const [results] = await db.query('select * from el_paper where state = ? and user_id=?', [state, userId])

        // 将查询结果映射为sys_user对象实例
        return results.map(item => new el_paper(
            item.id,
            item.user_id,
            item.depart_id,
            item.exam_id,
            item.title,
            item.total_time,
            item.user_time,
            item.total_score,
            item.qualify_score,
            item.obj_score,
            item.subj_score,
            item.user_score,
            item.has_saq,
            item.state,
            formatDateTime(item.create_time),
            formatDateTime(item.update_time),
            formatDateTime(item.limit_time),
        ))
    }

    /**
      * 根据试卷ID查询单个考试记录
      * 通过唯一标识符获取特定的考试答卷信息，包括考试详情、成绩、时间等完整数据
      * @param {string} id - 试卷的唯一标识符，用于精确查找特定考试记录
      * @returns {Promise<el_paper|null>} - 返回el_paper对象实例，如果未找到则返回null,只返回第一个结果（单个考试对象）
      */
    static async findPaperById(id) {
        // 执行SQL查询，获取所有用户数据
        const [results] = await db.query('select * from el_paper where id = ?', [id])

        const item = results[0]
        // 如果没有查询到结果，返回null
        if (results.length === 0) {
            return null;
        }

        // 只返回第一个结果（单个考试对象）
        return new el_paper(
            item.id,
            item.user_id,
            item.depart_id,
            item.exam_id,
            item.title,
            item.total_time,
            item.user_time,
            item.total_score,
            item.qualify_score,
            item.obj_score,
            item.subj_score,
            item.user_score,
            item.has_saq,
            item.state,
            formatDateTime(item.create_time),
            formatDateTime(item.update_time),
            formatDateTime(item.limit_time),
        )
    }

    /**
     * 根据考试ID和用户ID查询用户在该考试中的所有题目记录
     * 用于获取用户在特定考试中提交的所有题目答案，包括题目ID、用户答案、得分等详细信息
     * @param {string} exam_id 考试id
     * @param {string} user_id 用户id
     * @returns el_paper_qu对象实例数组
     */
    static async findPaperByExamIdAndUserId(exam_id, user_id) {
        const [results] = await db.query('select * from el_paper where exam_id=? and user_id=?', [exam_id, user_id])
        return results.map(item => ({
            "id": item.id,
            "userId": item.user_id,
            "departId": item.depart_id,
            "examId": item.exam_id,
            "title": item.title,
            "totalTime": item.total_time,
            "userTime": item.user_time,
            "totalScore": item.total_score,
            "qualifyScore": item.qualify_score,
            "objScore": item.obj_score,
            "subjScore": item.subj_score,
            "userScore": item.user_score,
            "hasSaq": item.has_saq == 1 ? true : false,
            "state": item.state,
            "createTime": formatDateTime(item.create_time),
            "updateTime": formatDateTime(item.update_time),
            "limitTime": formatDateTime(item.limit_time),
            "realName": item.real_name
        }))
    }

    /**
     * @param {el_paper} paper 考试试卷对象，包含所有必要的考试信息，如用户ID、部门ID、考试ID、标题、总时间、用户时间、总分数、及格分数、客观题分数、主观题分数、用户得分、是否有主观题、状态、截止时间（分钟）
     * @returns 
     */
    static async insertPaper(paper) {
        const { id, user_id, depart_id, exam_id, title, total_time, user_time, total_score, qualify_score, obj_score, subj_score, user_score, has_saq, state } = paper

        // 修复SQL语句：字段和参数数量必须匹配
        const [results] = await db.query(
            'INSERT INTO el_paper (id, user_id, depart_id, exam_id, title, total_time, user_time, total_score, qualify_score, obj_score, subj_score, user_score, has_saq, state, create_time, update_time, limit_time) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW(), DATE_ADD(NOW(), INTERVAL ? MINUTE))',
            [id, user_id, depart_id, exam_id, title, total_time, user_time, total_score, qualify_score, obj_score, subj_score, user_score, has_saq, state, total_time]
        )

        return results
    }



    /**
     * 根据试卷ID更新数据库中的用户时长
     * @param {string} id 试卷id
     * @param {number} user_time 用户时长
     * @returns 
     */
    static async updateUserTime(id, user_time) {
        // 执行SQL查询，更新用户时长
        const [results] = await db.query('update el_paper set user_time=? where id=?', [user_time, id])
        return results
    }


    /**
    * 根据试卷ID更新用户时长和状态
    * 用于在考试结束后更新用户的考试时长和状态，通常在用户提交试卷后调用
    * @param {string} id - 试卷的唯一标识符，用于精确查找特定考试记录
    * @param {number} user_time - 用户在考试中花费的总时长（分钟）
    * @param {number} state - 考试状态，2表示已考完
    * @returns {Promise<number>} - 返回受影响的行数，通常为1表示成功更新
    */
    static async updateUserTimeAndState(id, user_time, state) {
        //更新用户时长和状态
        const [results] = await db.query('update el_paper set user_time=?, state=? where id=?', [user_time, state, id])
        return results
    }

    /**
     * 根据试卷ID更新用户得分
     * 用于在考试结束后更新用户的考试得分，通常在用户提交试卷后调用
     * @param {string} id - 试卷的唯一标识符，用于精确查找特定考试记录
     * @param {number} objScore - 用户在考试中的客观题得分
     * @param {number} subjScore - 用户在考试中的主观题得分
     * @param {number} userScore - 用户在考试中的总得分
     * @returns {Promise<number>} - 返回受影响的行数，通常为1表示成功更新
     */
    static async updateUserScore(objScore, subjScore, userScore, id) {
        //更新用户得分
        const [results] = await db.query(
            'update el_paper set obj_score=?, subj_score=?, user_score=?  where id=?',
            [objScore, subjScore, userScore, id]
        )
        return results
    }

    static async updateUpdateTime(id) {
        //更新更新时间
        const [results] = await db.query('update el_paper set update_time=NOW() where id=?', [id])
        return results
    }






}

module.exports = el_paper;